home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 19 / Mac Magazin and MacEasy Magazine CD - Issue 19.iso / Utilities / uae-0.4 / Source Code / cia.c < prev    next >
Text File  |  1996-02-05  |  14KB  |  652 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * CIA chip support
  5.   *
  6.   * Copyright 1995 Bernd Schmidt, Alessandro Bissacco
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <time.h>
  12.  
  13. #include "config.h"
  14. #include "amiga.h"
  15. #include "options.h"
  16. #include "events.h"
  17. #include "memory.h"
  18. #include "custom.h"
  19. #include "cia.h"
  20. #include "disk.h"
  21. #include "xwin.h"
  22. #include "keybuf.h"
  23.  
  24. #define DIV10 5 /* Yes, a bad identifier. */
  25.  
  26. static UBYTE ciaaicr,ciaaimask,ciabicr,ciabimask;
  27. static UBYTE ciaacra,ciaacrb,ciabcra,ciabcrb;
  28. static ULONG ciaata,ciaatb,ciabta,ciabtb;
  29. static UWORD ciaala,ciaalb,ciabla,ciablb;
  30. static ULONG ciaatod,ciabtod,ciaatol,ciabtol,ciaaalarm,ciabalarm;
  31. static bool ciaatlatch,ciabtlatch;
  32. static UBYTE ciaapra,ciaaprb,ciaadra,ciaadrb,ciaasdr;
  33. static UBYTE ciabpra,ciabprb,ciabdra,ciabdrb,ciabsdr; 
  34. static int div10;
  35. static int kbstate;
  36. static bool kback;
  37.  
  38. static void setclr(UBYTE *p, UBYTE val)
  39. {
  40.     if (val & 0x80) {
  41.     *p |= val & 0x7F;
  42.     } else {
  43.     *p &= ~val;
  44.     }
  45. }
  46.  
  47. static void RethinkICRA(void)
  48. {
  49.     if (ciaaimask & ciaaicr) {
  50.     ciaaicr |= 0x80;
  51.     custom_bank.wput(0xDFF09C,0x8008);
  52.     } else {
  53.     ciaaicr &= 0x7F;
  54.     custom_bank.wput(0xDFF09C,0x0008);
  55.     }
  56. }
  57.  
  58. static void RethinkICRB(void)
  59. {
  60.     if (ciabimask & ciabicr) {
  61.     ciabicr |= 0x80;
  62.     custom_bank.wput(0xDFF09C,0xA000);
  63.     } else {
  64.     ciabicr &= 0x7F;
  65.     custom_bank.wput(0xDFF09C,0x2000);
  66.     }
  67. }
  68.  
  69. static int lastdiv10;
  70.  
  71. static void CIA_update(void)
  72. {
  73.     unsigned long int ccount = cycles - eventtab[ev_cia].oldcycles + lastdiv10;
  74.     unsigned long int ciaclocks = ccount / DIV10;
  75.  
  76.     int aovfla = 0, aovflb = 0, bovfla = 0, bovflb = 0;
  77.  
  78.     lastdiv10 = div10;
  79.     div10 = ccount % DIV10;
  80.     
  81.     /* CIA A timers */
  82.     if ((ciaacra & 0x21) == 0x01) {
  83.     assert((ciaata+1) >= ciaclocks);
  84.     if ((ciaata+1) == ciaclocks) {
  85.         aovfla = 1;
  86.         if ((ciaacrb & 0x61) == 0x41) {
  87.         if (ciaatb-- == 0) aovflb = 1;        
  88.         }
  89.     }         
  90.     ciaata -= ciaclocks;
  91.     }
  92.     if ((ciaacrb & 0x61) == 0x01) {
  93.     assert((ciaatb+1) >= ciaclocks);
  94.     if ((ciaatb+1) == ciaclocks) aovflb = 1;
  95.     ciaatb -= ciaclocks;
  96.     }
  97.     
  98.     /* CIA B timers */
  99.     if ((ciabcra & 0x21) == 0x01) {
  100.     assert((ciabta+1) >= ciaclocks);
  101.     if ((ciabta+1) == ciaclocks) {
  102.         bovfla = 1;
  103.         if ((ciabcrb & 0x61) == 0x41) {
  104.         if (ciabtb-- == 0) bovflb = 1;
  105.         }
  106.     } 
  107.     ciabta -= ciaclocks;
  108.     }
  109.     if ((ciabcrb & 0x61) == 0x01) {
  110.     assert ((ciabtb+1) >= ciaclocks);
  111.     if ((ciabtb+1) == ciaclocks) bovflb = 1;
  112.     ciabtb -= ciaclocks;
  113.     }
  114.     if (aovfla) {
  115.     ciaaicr |= 1; RethinkICRA();
  116.     ciaata = ciaala;
  117.     if (ciaacra & 0x8) ciaacra &= ~1;
  118.     }
  119.     if (aovflb) {
  120.     ciaaicr |= 2; RethinkICRA();
  121.     ciaatb = ciaalb;
  122.     if (ciaacrb & 0x8) ciaacrb &= ~1;
  123.     }
  124.     if (bovfla) {
  125.     ciabicr |= 1; RethinkICRB();
  126.     ciabta = ciabla;
  127.     if (ciabcra & 0x8) ciabcra &= ~1;
  128.     }
  129.     if (bovflb) {
  130.     ciabicr |= 2; RethinkICRA();
  131.     ciabtb = ciablb;
  132.     if (ciabcrb & 0x8) ciabcrb &= ~1;
  133.     }
  134. }
  135.  
  136. static void CIA_calctimers(void)
  137. {
  138.     int ciaatimea = -1, ciaatimeb = -1, ciabtimea = -1, ciabtimeb = -1;
  139.  
  140.     eventtab[ev_cia].oldcycles = cycles;
  141.     
  142.     if ((ciaacra & 0x21) == 0x01) {
  143.     ciaatimea = (DIV10-div10) + DIV10*ciaata;    
  144.     }
  145.     if ((ciaacrb & 0x61) == 0x41) {
  146.     /* Timer B will not get any pulses if Timer A is off. */
  147.     if (ciaatimea >= 0) {
  148.         /* If Timer A is in one-shot mode, and Timer B needs more than
  149.          * one pulse, it will not underflow. */
  150.         if (ciaatb == 0 || (ciaacra & 0x8) == 0) {
  151.         /* Otherwise, we can determine the time of the underflow. */
  152.         ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
  153.         }
  154.     }
  155.     }
  156.     if ((ciaacrb & 0x61) == 0x01) {
  157.     ciaatimeb = (DIV10-div10) + DIV10*ciaatb;
  158.     }
  159.  
  160.     if ((ciabcra & 0x21) == 0x01) {
  161.     ciabtimea = (DIV10-div10) + DIV10*ciabta;    
  162.     }
  163.     if ((ciabcrb & 0x61) == 0x41) {
  164.     /* Timer B will not get any pulses if Timer A is off. */
  165.     if (ciabtimea >= 0) {
  166.         /* If Timer A is in one-shot mode, and Timer B needs more than
  167.          * one pulse, it will not underflow. */
  168.         if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
  169.         /* Otherwise, we can determine the time of the underflow. */
  170.         ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
  171.         }
  172.     }
  173.     }
  174.     if ((ciabcrb & 0x61) == 0x01) {
  175.     ciabtimeb = (DIV10-div10) + DIV10*ciabtb;
  176.     }
  177.     eventtab[ev_cia].active = (ciaatimea != -1 || ciaatimeb != -1
  178.                    || ciabtimea != -1 || ciabtimeb != -1);
  179.     if (eventtab[ev_cia].active) {
  180.     unsigned long int ciatime = ~0L;
  181.     if (ciaatimea != -1) ciatime = ciaatimea;
  182.     if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
  183.     if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
  184.     if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
  185.     eventtab[ev_cia].evtime = ciatime;
  186.     }
  187.     events_schedule();
  188. }
  189.  
  190. void CIA_handler(void)
  191. {
  192.     CIA_update();
  193.     CIA_calctimers();
  194. }
  195.  
  196. void CIA_hsync_handler(void)
  197. {
  198.     static int keytime = 0;
  199.     
  200.     ciabtod++;
  201.     ciabtod &= 0xFFFFFF;
  202.     if (ciabtod == ciabalarm) {
  203.     ciabicr |= 4; RethinkICRB();
  204.     }
  205.     if (keys_available() && kback && (++keytime & 15) == 0) {
  206.     switch(kbstate) {
  207.      case 0:
  208.         ciaasdr = (BYTE)~0xFB; /* aaarghh... stupid compiler */
  209.         kbstate++;
  210.         break;
  211.      case 1:
  212.         kbstate++;
  213.         ciaasdr = (BYTE)~0xFD;
  214.         break;
  215.      case 2:
  216.         ciaasdr = ~get_next_key();
  217.         break;
  218.     }
  219.     ciaaicr |= 8; RethinkICRA();
  220.     }
  221. }
  222.  
  223. void CIA_vsync_handler()
  224. {    
  225.     ciaatod++;
  226.     ciaatod &= 0xFFFFFF;
  227.     if (ciaatod == ciaaalarm) {
  228.     ciaaicr |= 4; RethinkICRA();
  229.     }
  230. }
  231.  
  232. static UBYTE ReadCIAA(UWORD addr)
  233. {
  234.     UBYTE tmp;
  235.     
  236.     switch(addr & 0xf){
  237.      case 0: 
  238.     tmp = (DISK_status() & 0x3C);
  239.     if (!buttonstate[0]) tmp |= 0x40;
  240.     if (!buttonstate[1]) tmp |= 0x80;
  241.     return tmp;
  242.      case 1:
  243.     return ciaaprb;
  244.      case 2:
  245.     return ciaadra;
  246.      case 3:
  247.     return ciaadrb;
  248.      case 4:
  249.     return ciaata & 0xff;
  250.      case 5:
  251.     return ciaata >> 8;
  252.      case 6:
  253.     return ciaatb & 0xff;
  254.      case 7:
  255.     return ciaatb >> 8;
  256.      case 8:
  257.     if (ciaatlatch) {
  258.         ciaatlatch = 0;
  259.         return ciaatol & 0xff;
  260.     } else return ciaatod & 0xff;
  261.      case 9:
  262.     if (ciaatlatch) return (ciaatol >> 8) & 0xff;
  263.     else return (ciaatod >> 8) & 0xff;
  264.      case 10:
  265.     ciaatlatch = 1; ciaatol = ciaatod; /* ??? only if not already latched? */
  266.     return (ciaatol >> 16) & 0xff;
  267.      case 12:
  268.     return ciaasdr;
  269.      case 13:
  270.     tmp = ciaaicr; ciaaicr = 0; RethinkICRA(); return tmp;
  271.      case 14:
  272.     return ciaacra;
  273.      case 15:
  274.     return ciaacrb;
  275.     }
  276.     return 0;
  277. }
  278.  
  279. static UBYTE ReadCIAB(UWORD addr)
  280. {
  281.     UBYTE tmp;
  282.     
  283.     switch(addr & 0xf){
  284.      case 0: 
  285.     return ciabpra;
  286.      case 1:
  287.     return ciabprb;
  288.      case 2:
  289.     return ciabdra;
  290.      case 3:
  291.     return ciabdrb;
  292.      case 4:
  293.     return ciabta & 0xff;
  294.      case 5:
  295.     return ciabta >> 8;
  296.      case 6:
  297.     return ciabtb & 0xff;
  298.      case 7:
  299.     return ciabtb >> 8;
  300.      case 8:
  301.     if (ciabtlatch) {
  302.         ciabtlatch = 0;
  303.         return ciabtol & 0xff;
  304.     } else return ciabtod & 0xff;
  305.      case 9:
  306.     if (ciabtlatch) return (ciabtol >> 8) & 0xff;
  307.     else return (ciabtod >> 8) & 0xff;
  308.      case 10:
  309.     ciabtlatch = 1; ciabtol = ciabtod;
  310.     return (ciabtol >> 16) & 0xff;
  311.      case 12:
  312.     return ciabsdr;
  313.      case 13:
  314.     tmp = ciabicr; ciabicr = 0; RethinkICRB();
  315.     if (!dskdmaen)
  316.         if (indexpulse == 0){
  317.         tmp |= 0x10;
  318.         DISK_Index();
  319.         indexpulse = 100; /* whatever */
  320.         } else {
  321.         indexpulse--;
  322.         }        
  323.     return tmp;
  324.      case 14:
  325.     return ciabcra;
  326.      case 15:
  327.     return ciabcrb;
  328.     }
  329.     return 0;
  330. }
  331.  
  332. static void WriteCIAA(UWORD addr,UBYTE val)
  333. {
  334.     switch(addr & 0xf){
  335.      case 0: 
  336.     ciaapra = (ciaapra & ~0x3) | (val & 0x3); LED(ciaapra & 0x2); break;
  337.      case 1:
  338.     ciaaprb = val; break;
  339.      case 2:
  340.     ciaadra = val; break;
  341.      case 3:
  342.     ciaadrb = val; break;
  343.      case 4:
  344.     CIA_update();
  345.     ciaala = (ciaala & 0xff00) | val;
  346.     CIA_calctimers();
  347.     break;
  348.      case 5:
  349.     CIA_update();
  350.     ciaala = (ciaala & 0xff) | (val << 8);
  351.     if ((ciaacra & 1) == 0) {
  352.         ciaata = ciaala;
  353.     }
  354.     if (ciaacra & 8) { 
  355.         ciaata = ciaala; 
  356.         ciaacra |= 1; 
  357.     }/*??? load latch always? */
  358.     CIA_calctimers();
  359.     break;
  360.      case 6:
  361.     CIA_update();
  362.     ciaalb = (ciaalb & 0xff00) | val;
  363.     CIA_calctimers();
  364.     break;
  365.      case 7:
  366.     CIA_update();
  367.     ciaalb = (ciaalb & 0xff) | (val << 8);
  368.     if ((ciaacrb & 1) == 0) ciaatb = ciaalb;
  369.     if (ciaacrb & 8) { ciaatb = ciaalb; ciaacrb |= 1; }
  370.     CIA_calctimers();
  371.     break;
  372.      case 8:
  373.     if (ciaacrb & 0x80){
  374.         ciaaalarm = (ciaaalarm & ~0xff) | val;
  375.     } else {
  376.         ciaatod = (ciaatod & ~0xff) | val;
  377.     }
  378.     break;
  379.      case 9:
  380.     if (ciaacrb & 0x80){
  381.         ciaaalarm = (ciaaalarm & ~0xff00) | (val << 8);
  382.     } else {
  383.         ciaatod = (ciaatod & ~0xff00) | (val << 8);
  384.     }
  385.     break;
  386.      case 10:
  387.     if (ciaacrb & 0x80){
  388.         ciaaalarm = (ciaaalarm & ~0xff0000) | (val << 16);
  389.     } else {
  390.         ciaatod = (ciaatod & ~0xff0000) | (val << 16);
  391.     }
  392.     break;
  393.      case 12:
  394.     ciaasdr = val; break;
  395.      case 13:
  396.     setclr(&ciaaimask,val); break; /* ??? call RethinkICR() ? */
  397.      case 14:
  398.     CIA_update();
  399.     ciaacra = val;
  400.     if (ciaacra & 0x10){
  401.         ciaacra &= ~0x10;
  402.         ciaata = ciaala;
  403.     }
  404.     if (ciaacra & 0x40) {
  405.         kback = true;
  406.     }
  407.     CIA_calctimers();
  408.     break;
  409.      case 15:
  410.     CIA_update();
  411.     ciaacrb = val; 
  412.     if (ciaacrb & 0x10){
  413.         ciaacrb &= ~0x10;
  414.         ciaatb = ciaalb;
  415.     }
  416.     CIA_calctimers();
  417.     break;
  418.     }
  419. }
  420.  
  421. static void WriteCIAB(UWORD addr,UBYTE val)
  422. {
  423.     switch(addr & 0xf){
  424.      case 0:
  425.     ciabpra = (ciabpra & ~0x3) | (val & 0x3); break;
  426.      case 1:
  427.     ciabprb = val; DISK_select(val); break;
  428.      case 2:
  429.     ciabdra = val; break;
  430.      case 3:
  431.     ciabdrb = val; break;
  432.      case 4:
  433.     CIA_update();
  434.     ciabla = (ciabla & 0xff00) | val;
  435.     CIA_calctimers();
  436.     break;
  437.      case 5:
  438.     CIA_update();
  439.     ciabla = (ciabla & 0xff) | (val << 8);
  440.     if ((ciabcra & 1) == 0) ciabta = ciabla;
  441.     if (ciabcra & 8) { ciabta = ciabla; ciabcra |= 1; } 
  442.     CIA_calctimers();
  443.     break;
  444.      case 6:
  445.     CIA_update();
  446.     ciablb = (ciablb & 0xff00) | val;
  447.     CIA_calctimers();
  448.     break;
  449.      case 7:
  450.     CIA_update();
  451.     ciablb = (ciablb & 0xff) | (val << 8);
  452.     if ((ciabcrb & 1) == 0) ciabtb = ciablb;
  453.     if (ciabcrb & 8) { ciabtb = ciablb; ciabcrb |= 1; }
  454.     CIA_calctimers();
  455.     break;
  456.      case 8:
  457.     if (ciabcrb & 0x80){
  458.         ciabalarm = (ciabalarm & ~0xff) | val;
  459.     } else {
  460.         ciabtod = (ciabtod & ~0xff) | val;
  461.     }
  462.     break;
  463.      case 9:
  464.     if (ciabcrb & 0x80){
  465.         ciabalarm = (ciabalarm & ~0xff00) | (val << 8);
  466.     } else {
  467.         ciabtod = (ciabtod & ~0xff00) | (val << 8);
  468.     }
  469.     break;
  470.      case 10:
  471.     if (ciabcrb & 0x80){
  472.         ciabalarm = (ciabalarm & ~0xff0000) | (val << 16);
  473.     } else {
  474.         ciabtod = (ciabtod & ~0xff0000) | (val << 16);
  475.     }
  476.     break;
  477.      case 12:
  478.     ciabsdr = val; 
  479.     break;
  480.      case 13:
  481.     setclr(&ciabimask,val); 
  482.     break;
  483.      case 14:
  484.     CIA_update();
  485.     ciabcra = val;
  486.     if (ciabcra & 0x10){
  487.         ciabcra &= ~0x10;
  488.         ciabta = ciabla;
  489.     }
  490.     CIA_calctimers();
  491.     break;
  492.      case 15:
  493.     CIA_update();
  494.     ciabcrb = val; 
  495.     if (ciabcrb & 0x10){
  496.         ciabcrb &= ~0x10;
  497.         ciabtb = ciablb;
  498.     }
  499.     CIA_calctimers();
  500.     break;
  501.     }
  502. }
  503.  
  504. void CIA_reset(void)
  505. {
  506.     kback = true;
  507.     kbstate = 0;
  508.     
  509.     ciaatlatch = ciabtlatch = 0;
  510.     ciaatod = ciabtod = 0;
  511.     ciaaicr = ciabicr = ciaaimask = ciabimask = 0;
  512.     ciaacra = ciaacrb = ciabcra = ciabcrb = 0x4; /* outmode = toggle; */
  513.     div10 = 0;
  514.     lastdiv10 = 0;
  515.     CIA_calctimers();
  516. }
  517.  
  518. void dumpcia(void)
  519. {
  520.     printf("A: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  521.        (int)ciaacra, (int)ciaacrb, (int)ciaaimask, ciaatod, 
  522.        ciaatlatch ? " latched" : "", ciaata, ciaatb);
  523.     printf("B: CRA: %02x, CRB: %02x, IMASK: %02x, TOD: %08lx %7s TA: %04lx, TB: %04lx\n",
  524.        (int)ciabcra, (int)ciabcrb, (int)ciabimask, ciabtod, 
  525.        ciabtlatch ? " latched" : "", ciabta, ciabtb);
  526. }
  527.  
  528. /* CIA memory access */
  529.  
  530. static ULONG cia_lget(CPTR) REGPARAM;
  531. static UWORD cia_wget(CPTR) REGPARAM;
  532. static UBYTE cia_bget(CPTR) REGPARAM;
  533. static void  cia_lput(CPTR, ULONG) REGPARAM;
  534. static void  cia_wput(CPTR, UWORD) REGPARAM;
  535. static void  cia_bput(CPTR, UBYTE) REGPARAM;
  536.  
  537. addrbank cia_bank = {
  538.     cia_lget, cia_wget, cia_bget,
  539.     cia_lput, cia_wput, cia_bput,
  540.     default_xlate, default_check
  541. };
  542.  
  543. ULONG cia_lget(CPTR addr)
  544. {
  545.     return cia_bget(addr+3);
  546. }
  547.  
  548. UWORD cia_wget(CPTR addr)
  549. {
  550.     return cia_bget(addr+1);
  551. }
  552.  
  553. UBYTE cia_bget(CPTR addr)
  554. {
  555. #ifdef DUALCPU
  556.     customacc = true;
  557. #endif
  558.     if ((addr & 0xF0FF) == 0xE001)
  559.         return ReadCIAA((addr & 0xF00) >> 8);
  560.     if ((addr & 0xF0FF) == 0xD000)
  561.         return ReadCIAB((addr & 0xF00) >> 8);
  562.     return 0;
  563. }
  564.  
  565. void cia_lput(CPTR addr, ULONG value)
  566. {
  567.     cia_bput(addr+3,value); /* FIXME ? */
  568. }
  569.  
  570. void cia_wput(CPTR addr, UWORD value)
  571. {
  572.     cia_bput(addr+1,value);
  573. }
  574.  
  575. void cia_bput(CPTR addr, UBYTE value)
  576. {
  577. #ifdef DUALCPU
  578.     customacc = true;
  579. #endif
  580.     if ((addr & 0xF0FF) == 0xE001)
  581.         WriteCIAA((addr & 0xF00) >> 8,value);
  582.     if ((addr & 0xF0FF) == 0xD000)
  583.         WriteCIAB((addr & 0xF00) >> 8,value);
  584. }
  585.  
  586. /* battclock memory access */
  587.  
  588. static ULONG clock_lget(CPTR) REGPARAM;
  589. static UWORD clock_wget(CPTR) REGPARAM;
  590. static UBYTE clock_bget(CPTR) REGPARAM;
  591. static void  clock_lput(CPTR, ULONG) REGPARAM;
  592. static void  clock_wput(CPTR, UWORD) REGPARAM;
  593. static void  clock_bput(CPTR, UBYTE) REGPARAM;
  594.  
  595. addrbank clock_bank = {
  596.     clock_lget, clock_wget, clock_bget,
  597.     clock_lput, clock_wput, clock_bput,
  598.     default_xlate, default_check
  599. };
  600.  
  601. ULONG clock_lget(CPTR addr)
  602. {
  603.     return clock_bget(addr+3);
  604. }
  605.  
  606. UWORD clock_wget(CPTR addr)
  607. {
  608.     return clock_bget(addr+1);
  609. }
  610.  
  611. UBYTE clock_bget(CPTR addr)
  612. {
  613. #ifdef DUALCPU
  614.     customacc = true;
  615. #endif
  616.     
  617.     time_t t=time(0);
  618.     struct tm *ct;
  619.     ct=localtime(&t);
  620.     switch (addr & 0x3f)
  621.     {
  622.      case 0x03: return ct->tm_sec % 10;
  623.      case 0x07: return ct->tm_sec / 10;
  624.      case 0x0b: return ct->tm_min % 10;
  625.      case 0x0f: return ct->tm_min / 10;
  626.      case 0x13: return ct->tm_hour % 10;
  627.      case 0x17: return ct->tm_hour / 10;
  628.      case 0x1b: return ct->tm_mday % 10;
  629.      case 0x1f: return ct->tm_mday / 10;
  630.      case 0x23: return (ct->tm_mon+1) % 10;
  631.      case 0x27: return (ct->tm_mon+1) / 10;
  632.      case 0x2b: return ct->tm_year % 10;
  633.      case 0x2f: return ct->tm_year / 10;
  634.     }
  635.     return 0;
  636. }
  637.  
  638. void clock_lput(CPTR addr, ULONG value)
  639. {
  640.     /* No way */
  641. }
  642.  
  643. void clock_wput(CPTR addr, UWORD value)
  644. {
  645.     /* No way */
  646. }
  647.  
  648. void clock_bput(CPTR addr, UBYTE value)
  649. {
  650.     /* No way */
  651. }
  652.